import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext
import json
import os
import sys

# 添加项目根目录到路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from main import decode_message
from protocol.codec import from_hex


class DecodePanel:
    def __init__(self, parent, versions, active_profile):
        self.parent = parent
        self.versions = versions
        self.active_profile = active_profile
        self.last_parsed_data = None
        
        # 创建主框架
        self.frame = ttk.LabelFrame(parent, text="", padding=10)
        
        self.setup_ui()
        
    def setup_ui(self):
        """设置解码面板界面"""
        # 版本选择
        version_frame = ttk.Frame(self.frame)
        version_frame.pack(fill=tk.X, pady=(0, 10))
        
        ttk.Label(version_frame, text="协议版本:").pack(side=tk.LEFT)
        self.version_var = tk.StringVar(value=self.active_profile)
        self.version_combo = ttk.Combobox(version_frame, textvariable=self.version_var, 
                                         values=list(self.versions.keys()), state="readonly")
        self.version_combo.pack(side=tk.LEFT, padx=(5, 0))
        self.version_combo.bind("<<ComboboxSelected>>", self.on_version_changed)
        
        # 数据输入区域
        input_frame = ttk.LabelFrame(self.frame, text="数据输入", padding=5)
        input_frame.pack(fill=tk.X, pady=(0, 10))
        
        ttk.Label(input_frame, text="十六进制数据:").pack(anchor=tk.W)
        self.input_text = scrolledtext.ScrolledText(input_frame, height=6, wrap=tk.WORD, font=('Consolas', 10))
        self.input_text.pack(fill=tk.X, pady=(5, 0))
        
        # 启用撤销/重做功能
        self.input_text.config(undo=True)
        
        # 绑定键盘快捷键
        self.input_text.bind('<Control-z>', self.undo)
        self.input_text.bind('<Control-y>', self.redo)
        self.input_text.bind('<Control-Z>', self.undo)  # 大写Z
        self.input_text.bind('<Control-Y>', self.redo)  # 大写Y
        
        # 操作按钮
        button_frame = ttk.Frame(self.frame)
        button_frame.pack(fill=tk.X, pady=(0, 10))
        
        ttk.Button(button_frame, text="解析数据帧", command=self.parse_frame).pack(side=tk.LEFT)
        
        # 解析结果显示
        result_frame = ttk.LabelFrame(self.frame, text="解析结果", padding=5)
        result_frame.pack(fill=tk.BOTH, expand=True)
        
        # 使用简单的文本编辑器，设置合适的高度和滚动条
        self.json_text = scrolledtext.ScrolledText(result_frame, height=12, wrap=tk.WORD, font=('Consolas', 10))
        self.json_text.pack(fill=tk.BOTH, expand=True)
        
    def parse_frame(self):
        """解析数据帧"""
        hex_data = self.input_text.get(1.0, tk.END).strip()
        if not hex_data:
            messagebox.showwarning("警告", "请输入十六进制数据")
            return
            
        try:
            # 转换十六进制字符串为字节
            frame_bytes = from_hex(hex_data)
            
            # 使用main.py中的函数解析数据帧
            formatted_result = decode_message(frame_bytes, self.active_profile)
            self.last_parsed_data = formatted_result
            
            # 检查是否有错误信息
            body = formatted_result.get('body', {})
            if 'error' in body:
                # 显示错误信息并弹出警告
                error_msg = body['error']
                messagebox.showwarning("解析警告", f"无法完全解析数据帧:\n{error_msg}\n\n原始数据已显示在结果中。")
            
            # 显示解析结果
            formatted_json = json.dumps(formatted_result, indent=2, ensure_ascii=False)
            self.json_text.delete('1.0', tk.END)
            self.json_text.insert('1.0', formatted_json)
            
        except ValueError as e:
            # 清空输出结果
            self.json_text.delete('1.0', tk.END)
            self.last_parsed_data = None
            if "不是合法的十六进制" in str(e):
                messagebox.showerror("十六进制格式错误", f"输入的数据不是合法的十六进制格式:\n{str(e)}\n\n请确保输入的是有效的十六进制字符串（如：7E 02 00 00 01）。")
            else:
                messagebox.showerror("数据格式错误", f"数据格式验证失败: {str(e)}")
        except Exception as e:
            # 清空输出结果
            self.json_text.delete('1.0', tk.END)
            self.last_parsed_data = None
            messagebox.showerror("解析数据帧失败", f"解析数据帧时发生错误: {str(e)}")
            
    def undo(self, event=None):
        """撤销操作"""
        try:
            self.input_text.edit_undo()
        except tk.TclError:
            pass  # 没有可撤销的操作
        return "break"  # 阻止默认行为
    
    def redo(self, event=None):
        """重做操作"""
        try:
            self.input_text.edit_redo()
        except tk.TclError:
            pass  # 没有可重做的操作
        return "break"  # 阻止默认行为
            
    def on_version_changed(self, event=None):
        """版本改变时的处理"""
        self.active_profile = self.version_var.get()
        # 清空输出结果，但保留输入内容
        self.json_text.delete('1.0', tk.END)
                    
    def get_parsed_data(self):
        """获取解析的数据"""
        return self.last_parsed_data
